#pragma once
#include "Dispatcher.h"
#include "Channel.h"
#include <thread>
#include <assert.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <map>
#include <mutex>
using namespace std;


enum class ElemType:char{ADD, DELETE, MODIFY};

struct ChannelElement
{
    ElemType type;
    Channel* channel;
};
class Dispatcher;

class EventLoop
{
public:
    EventLoop();
    EventLoop(const string threadName);
    ~EventLoop();
    int run();
    int eventActive(int fd, int event);
    int addTask(struct Channel* channel, ElemType type);
    int processTaskQ();
    int add(Channel* channel);
    int remove(Channel* channel);
    int modify(Channel* channel);
    int freeChannel(Channel* channel);
    int readMessage();
    inline thread::id getThreadID()
    {
        return m_threadID;
    }
    inline string getThreadName()
    {
        return m_threadName;
    }
    static int readLocalMessage(void* arg);

private:
    void taskWakeup();

private:
    bool m_isQuit;
    Dispatcher* m_dispatcher;
    queue<ChannelElement*> m_taskQ;
    map<int, Channel*> m_channelMap;
    thread::id m_threadID;
    string m_threadName;
    mutex m_mutex;
    int m_socketPair[2];
};


